package com.jnsw.gps;

/**
 * 坐标转换
 */
public class GaussConvert
{
	private GaussParamter m_paramter;   //可读可写，变量
	public double a, b, c, d;
    public double XScent;
    public double YScent;
    public double XDcent;
    public double YDcent;

	public GaussConvert(int beltwidth,int beltNum,double a1,double b1,double c1,double d1,double dxScent,double dyScent,double dxDecent,double dyDecent)
	{
		m_paramter = new GaussParamter();
		m_paramter.setbeltWidth(beltwidth);
		m_paramter.setbeltNum(beltNum);
		Spheroid tuoQiuJiChun = new Spheroid("WGS-84坐标系", 6378137, 6356752.3142);
		m_paramter.setTuoQiuJiChun(tuoQiuJiChun);
		a =a1;
		b=b1;
		c=c1;
		d=d1;
		XScent = dxScent;
		YScent = dyScent;
		XDcent = dxDecent;
		YDcent = dyDecent;
		
	}
	
	public GPSPoint FourtConvert(GPSPoint point)
	{
		GPSPoint pointd = new GPSPoint(0,0);
		point.x = point.x -  XScent;// CoordsTranslateProject..SwitchPara.XScent;
		point.y = point.y -  YScent;//CoordsTranslateProject.Coords.SwitchPara.YScent;
		
		pointd.x = point.x + a - point.y * c + point.x * d +  XDcent;
        pointd.y = point.y + b + point.x * c + point.y * d +  YDcent;
		
		return pointd;
	}
	public GPSPoint WGS84ToLocal(GPSPoint lb)
	{
		GPSPoint lxy = positive(lb);
		
		
		return FourtConvert(lxy);
	}
	
	public GPSPoint positive(GPSPoint lb)
	{
		this.m_paramter.setB(lb.x);
		this.m_paramter.setL(lb.y);
		double beltNum; //带号
        beltNum = Math.ceil((this.m_paramter.getL() - (this.m_paramter.getbeltWidth() == 3 ? 1.5 : 0)) / this.m_paramter.getbeltWidth());
        if (this.m_paramter.getbeltWidth() == 3 && beltNum * 3 == this.m_paramter.getL() - 1.5) beltNum += 1;
        m_paramter.setbeltNum ( (int)beltNum);
        double L = this.m_paramter.getL() - (beltNum * this.m_paramter.getbeltWidth() - (this.m_paramter.getbeltWidth() == 6 ? 3 : 0)); //中央经线的度数
        double rB, tB, m;
        rB = this.m_paramter.getB() * Math.PI / 180;
        tB = Math.tan(rB);
        //tL = L*Math.PI/180;
        m = Math.cos(rB) * L * Math.PI / 180;
        double N = this.m_paramter.getTuoQiuJiChun().getLong() / Math.sqrt(1 - this.m_paramter.getTuoQiuJiChun().FirstE() * Math.sin(rB) * Math.sin(rB));
        double it2 = this.m_paramter.getTuoQiuJiChun().SecondE() * Math.pow(Math.cos(rB), 2);
        double x = 0.5 * m * m + (double)1 / 24 * (5 - tB * tB + 9 * it2 + 4 * it2 * it2) * Math.pow(m, 4) + (double)1 / 720 * (61 - 58 * tB * tB + Math.pow(tB, 4)) * Math.pow(m, 6);
        //double x = 0.5 * Math.Sin(rB) * Math.Cos(rB) * Math.Pow(tL, 2) + (1.0 / 24) * Math.Sin(rB) * Math.Pow(Math.Cos(rB), 3) * (5 - tB * tB + 9 * it2 + 4 * it2 * it2) * Math.Pow(tL, 4) + (1.0 / 720) * Math.Sin(rB) * Math.Pow(Math.Cos(rB), 5) * (61 - 58 * tB * tB + Math.Pow(tB, 4)) * Math.Pow(tL, 6);
        double m0 = this.m_paramter.getTuoQiuJiChun().getLong() * (1 - this.m_paramter.getTuoQiuJiChun().FirstE());
        double m2 = (double)3 / 2 * this.m_paramter.getTuoQiuJiChun().FirstE() * m0;
        double m4 = (double)5 / 4 * this.m_paramter.getTuoQiuJiChun().FirstE() * m2;
        double m6 = (double)7 / 6 * this.m_paramter.getTuoQiuJiChun().FirstE() * m4;
        double m8 = (double)9 / 8 * this.m_paramter.getTuoQiuJiChun().FirstE() * m6;
        double a0, a2, a4, a6, a8;
        a0 = m0 + (double)1 / 2 * m2 + (double)3 / 8 * m4 + (double)5 / 16 * m6 + (double)35 / 128 * m8;
        a2 = (double)1 / 2 * m2 + (double)1 / 2 * m4 + (double)15 / 32 * m6 + (double)7 / 16 * m8;
        a4 = (double)1 / 8 * m4 + (double)3 / 16 * m6 + (double)7 / 32 * m8;
        a6 = (double)1 / 32 * m6 + (double)1 / 16 * m8;
        a8 = (double)1 / 128 * m8;
        //求子午线弧长
        double X1 = a0 * rB - a2 * Math.sin(2 * rB) * 0.5 + (double)1 / 4 * a4 * Math.sin(4 * rB) - (double)1 / 6 * a6 * Math.sin(6 * rB) + (double)1 / 8 * a8 * Math.sin(8 * rB);
        this.m_paramter.setX ( X1 + N * x * tB);
        this.m_paramter.setY( N * (m + (double)1 / 6 * (1 - tB * tB + it2) * Math.pow(m, 3) + (double)1 / 720 * (5 - 18 * tB * tB + Math.pow(tB, 4) + 14 * it2 - 58 * tB * tB * it2) * Math.pow(m, 5)));
        
        GPSPoint lxy = new GPSPoint(0,0);
        lxy.x = this.m_paramter.getX();
        lxy.y= this.m_paramter.getY();
        
		return lxy;
	}
	
   	public class Spheroid
	{
		/// <summary>
        /// 椭球名称
        /// </summary>
		private String m_Name;
        
         
		/// <summary>
        /// 椭球长半轴
        /// </summary>
        private double m_Long;
        public double getLong()
        {
        	return m_Long;
        }
        
        
      /// <summary>
        /// 椭球短半轴
        /// </summary>
        private double m_Short;
        public double getShort()
        {
        	return m_Short;
        }
        
        /// <summary>
        /// 椭球扁率   只读不可写
        /// </summary>
        public double Alpha()
        {
        	return (this.m_Long - this.m_Short) / this.m_Long;
        }
         

        /// <summary>
        /// 第一偏心率的平方 只读不可写
        /// </summary>
        public double FirstE()
        {
            return (Spheroid.this.m_Long * Spheroid.this.m_Long - Spheroid.this.m_Short * Spheroid.this.m_Short) / (Spheroid.this.m_Long * Spheroid.this.m_Long);
            
        }
        /// <summary>
        /// 第二偏心率的平方 只读不可写
        /// </summary>
        public double SecondE()
        {
             return (this.m_Long * this.m_Long - this.m_Short * this.m_Short) / (this.m_Short * this.m_Short);
            
        }
        public Spheroid(String name, double long_radius, double short_radius)   //构造函数
        {
            this.m_Name = name;
            this.m_Long = long_radius;
            this.m_Short = short_radius;
        }
	}
    
	public class GaussParamter  //类里面定义了m_TuoQiuJiChun，m_B，m_L，m_H，m_X，m_Y，m_Z
    {
        private Spheroid m_TuoQiuJiChun;

        public Spheroid getTuoQiuJiChun()
        {
              return m_TuoQiuJiChun; 
             
        }
        public void setTuoQiuJiChun(Spheroid value)
        {
        	m_TuoQiuJiChun = value;
        }
        private double m_B;
        public double getB()
        {
           return m_B;  
        }
        public void setB(double value)
        {
        	m_B = value;
        }
        
        private double m_L;
        public double getL()
        {
            return m_L;  
          
        }
        public void setL(double value)
        {
        	 m_L = value;
        }
        
        private double m_X;

        public double getX()
        {
             return m_X;  
             
        }
        public void setX(double value)
        {
        	m_X = value;
        }

        private double m_Y;

        public double getY()
        {
            return m_Y; 
             
        }

        public void setY(double value)
        {
        	 m_Y = value;
        }
        
        private int m_beltWidth;

        public int getbeltWidth()
        {
            return m_beltWidth;  
            
        }
        
        public void setbeltWidth(int value)
        {
        	m_beltWidth = value;
        }
        
        private int m_beltNum;
        public int getbeltNum()
        {
            return m_beltNum;  
 
        }
        public void setbeltNum(int value)
        {
        	m_beltNum = value;
        }
    }

}
